package com.weifly.weistock.module.stockmonitor.impl;

import com.weifly.weistock.core.config.AbstractConfigService;
import com.weifly.weistock.core.config.ConfigConstants;
import com.weifly.weistock.core.constant.StockCatalogEnum;
import com.weifly.weistock.module.stockmonitor.StockMonitorStoreService;
import com.weifly.weistock.module.stockmonitor.bo.StockMonitorConfigBO;
import com.weifly.weistock.module.stockmonitor.bo.StockMonitorDayBO;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 股票监控存储服务实现
 *
 * @author weifly
 * @since 2021/6/11
 */
public class StockMonitorStoreServiceImpl extends AbstractConfigService implements StockMonitorStoreService {

    private static final String ATTR_TRADE_STOCK_CODE = "tradeStockCode";
    private static final String ATTR_UP_LOWEST_DAY = "up_lowest_day";
    private static final String ATTR_UP_LOWEST_PRICE = "up_lowest_price";
    private static final String ATTR_UP_DIFF = "up_diff";
    private static final String ATTR_UP_RATE = "up_rate";
    private static final String ATTR_UP_RATE_ALL_PERCENT = "up_rate_all_percent";
    private static final String ATTR_DOWN_HIGHEST_DAY = "down_highest_day";
    private static final String ATTR_DOWN_HIGHEST_PRICE = "down_highest_price";
    private static final String ATTR_DOWN_DIFF = "down_diff";
    private static final String ATTR_DOWN_RATE = "down_rate";
    private static final String ATTR_DOWN_RATE_ALL_PERCENT = "down_rate_all_percent";
    private static final String ATTR_DIFF_RATE_PERCENT = "diff_rate_percent";

    @Override
    public List<StockMonitorConfigBO> loadStockMonitorConfigList() {
        List<StockMonitorConfigBO> configList = new ArrayList<>();
        for (File xmlFile : this.getConfigFolder().listFiles()) {
            if (xmlFile.getName().endsWith(".xml")) {
                log.info("加载股票监控配置：" + xmlFile.getAbsolutePath());
                StockMonitorConfigBO configBO = this.loadConfigXml(xmlFile);
                configList.add(configBO);
            }
        }
        return configList;
    }

    private StockMonitorConfigBO loadConfigXml(File xmlFile) {
        StockMonitorConfigBO configBO = new StockMonitorConfigBO();
        try {
            SAXReader reader = new SAXReader();
            Document document = reader.read(xmlFile);
            Element rootEle = document.getRootElement();

            String stockCode = rootEle.attributeValue(ConfigConstants.ATTR_STOCK_CODE);
            configBO.setStockCode(stockCode);
            String stockName = rootEle.attributeValue(ConfigConstants.ATTR_STOCK_NAME);
            configBO.setStockName(stockName);
            String stockCatalog = rootEle.attributeValue(ConfigConstants.ATTR_STOCK_CATALOG);
            configBO.setStockCatalog(StockCatalogEnum.getByName(stockCatalog));
            String tradeStockCode = rootEle.attributeValue(ATTR_TRADE_STOCK_CODE);
            if (StringUtils.isNotBlank(tradeStockCode)) {
                configBO.setTradeStockCode(tradeStockCode);
            }

            List<Element> recordEleList = rootEle.elements(ConfigConstants.ELE_RECORD);
            if (recordEleList != null) {
                for (Element recordEle : recordEleList) {
                    StockMonitorDayBO dayBO = new StockMonitorDayBO();
                    String day = recordEle.attributeValue(ConfigConstants.ATTR_DAY);
                    dayBO.setDay(day);
                    // 收盘价
                    String closeStr = recordEle.attributeValue(ConfigConstants.ATTR_CLOSE);
                    if (StringUtils.isNotBlank(closeStr)) {
                        dayBO.setClose(Double.parseDouble(closeStr));
                    }
                    // diff
                    String diffStr = recordEle.attributeValue(ConfigConstants.ATTR_DIFF);
                    dayBO.setDiff(Double.parseDouble(diffStr));
                    // rate
                    String rateStr = recordEle.attributeValue(ConfigConstants.ATTR_RATE);
                    dayBO.setRate(Double.parseDouble(rateStr));
                    // up_lowest_day
                    String upLowestDay = recordEle.attributeValue(ATTR_UP_LOWEST_DAY);
                    if (StringUtils.isNotBlank(upLowestDay)) {
                        dayBO.setUp_lowest_day(upLowestDay);
                        dayBO.setUp_lowest_price(Double.parseDouble(recordEle.attributeValue(ATTR_UP_LOWEST_PRICE)));
                        dayBO.setUp_diff(Double.parseDouble(recordEle.attributeValue(ATTR_UP_DIFF)));
                        dayBO.setUp_rate(Double.parseDouble(recordEle.attributeValue(ATTR_UP_RATE)));
                        dayBO.setUp_rate_all_percent(Double.parseDouble(recordEle.attributeValue(ATTR_UP_RATE_ALL_PERCENT)));
                        dayBO.setDiff_rate_percent(Double.parseDouble(recordEle.attributeValue(ATTR_DIFF_RATE_PERCENT)));
                    }
                    // down_highest_day
                    String downHighestDay = recordEle.attributeValue(ATTR_DOWN_HIGHEST_DAY);
                    if (StringUtils.isNotBlank(downHighestDay)) {
                        dayBO.setDown_highest_day(downHighestDay);
                        dayBO.setDown_highest_price(Double.parseDouble(recordEle.attributeValue(ATTR_DOWN_HIGHEST_PRICE)));
                        dayBO.setDown_diff(Double.parseDouble(recordEle.attributeValue(ATTR_DOWN_DIFF)));
                        dayBO.setDown_rate(Double.parseDouble(recordEle.attributeValue(ATTR_DOWN_RATE)));
                        dayBO.setDown_rate_all_percent(Double.parseDouble(recordEle.attributeValue(ATTR_DOWN_RATE_ALL_PERCENT)));
                    }
                    configBO.getDayList().add(dayBO);
                }
            }
            return configBO;
        } catch (DocumentException e) {
            log.error("", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void saveStockMonitorConfig(StockMonitorConfigBO stockMonitorConfig) {
        DocumentFactory factory = DocumentFactory.getInstance();
        Document document = factory.createDocument();
        document.setXMLEncoding("UTF8");

        Element rootEle = factory.createElement(ConfigConstants.ELE_ROOT);
        document.setRootElement(rootEle);

        rootEle.addAttribute(ConfigConstants.ATTR_STOCK_CODE, stockMonitorConfig.getStockCode());
        rootEle.addAttribute(ConfigConstants.ATTR_STOCK_NAME, stockMonitorConfig.getStockName());
        rootEle.addAttribute(ConfigConstants.ATTR_STOCK_CATALOG, stockMonitorConfig.getStockCatalog().name());
        if (StringUtils.isNotBlank(stockMonitorConfig.getTradeStockCode())) {
            rootEle.addAttribute(ATTR_TRADE_STOCK_CODE, stockMonitorConfig.getTradeStockCode());
        }

        for (StockMonitorDayBO dayBO : stockMonitorConfig.getDayList()) {
            Element recordEle = factory.createElement(ConfigConstants.ELE_RECORD);
            recordEle.addAttribute(ConfigConstants.ATTR_DAY, dayBO.getDay());
            recordEle.addAttribute(ConfigConstants.ATTR_CLOSE, String.valueOf(dayBO.getClose()));
            recordEle.addAttribute(ConfigConstants.ATTR_DIFF, String.valueOf(dayBO.getDiff()));
            recordEle.addAttribute(ConfigConstants.ATTR_RATE, String.valueOf(dayBO.getRate()));
            if (StringUtils.isNotBlank(dayBO.getUp_lowest_day())) {
                recordEle.addAttribute(ATTR_UP_LOWEST_DAY, dayBO.getUp_lowest_day());
                recordEle.addAttribute(ATTR_UP_LOWEST_PRICE, String.valueOf(dayBO.getUp_lowest_price()));
                recordEle.addAttribute(ATTR_UP_DIFF, String.valueOf(dayBO.getUp_diff()));
                recordEle.addAttribute(ATTR_UP_RATE, String.valueOf(dayBO.getUp_rate()));
                recordEle.addAttribute(ATTR_UP_RATE_ALL_PERCENT, String.valueOf(dayBO.getUp_rate_all_percent()));
                recordEle.addAttribute(ATTR_DIFF_RATE_PERCENT, String.valueOf(dayBO.getDiff_rate_percent()));
            }
            if (StringUtils.isNotBlank(dayBO.getDown_highest_day())) {
                recordEle.addAttribute(ATTR_DOWN_HIGHEST_DAY, dayBO.getDown_highest_day());
                recordEle.addAttribute(ATTR_DOWN_HIGHEST_PRICE, String.valueOf(dayBO.getDown_highest_price()));
                recordEle.addAttribute(ATTR_DOWN_DIFF, String.valueOf(dayBO.getDown_diff()));
                recordEle.addAttribute(ATTR_DOWN_RATE, String.valueOf(dayBO.getDown_rate()));
                recordEle.addAttribute(ATTR_DOWN_RATE_ALL_PERCENT, String.valueOf(dayBO.getDown_rate_all_percent()));
            }
            rootEle.add(recordEle);
        }

        File xmlFile = new File(this.getConfigFolder(), "stockMonitor_" + stockMonitorConfig.getStockCode() + ".xml");
        log.info("保存股票监控信息, file={}", xmlFile.getAbsolutePath());
        this.saveConfig(xmlFile, document);
    }
}
